
import serial
import time
import os
import sys
import random
import re

DEBUG_PORT = "COM4"
BAUDRATE = 115200
AT_PORT = 'COM9'  # 根据实际情况修改端口号
#AT指令和返回值检查
# 定义变量
debug_serial = None

#记录运行次数
runTimes		= 0

#log文件
DEBUG_LOG		  = ""

# 创建日志文件
def creatLogFile():
 global DEBUG_LOG

 DEBUG_LOG = "DEBUG_LOG_{}.log".format(time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime()))

#log写入函数
def write_log(log,logFile=""):
 with open(logFile, 'a') as file_object:
  file_object.write(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + log+ "\r\n")
  print(log)

#发送at指令
def at_write(command, timeout, DEBUG_PORT_opened, at_result,RDY=0,CPIN=0):
 write_log(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())),DEBUG_LOG)
 at_command = command.encode("UTF-8")
 DEBUG_PORT_opened.write(at_command)

#读取at口返回
def at_read(serial_port, logFile=""):
 rec_str = ''
 while (True):
  time.sleep(1)
  lenth = serial_port.inWaiting()
  if lenth > 0:
   rec_str = serial_port.read(size=lenth)
   try:
    rec_str = re.sub('\\x1b.*?m', "", rec_str.decode("UTF-8"), 0, re.I)
    if logFile != "":
     with open(logFile, 'a') as file_object:
      rec_str = str(time.time()) + ":" + str(
       time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + rec_str
      file_object.write(
       str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + rec_str + "\r\n")
    return rec_str
   except:
    return ""
  else:
   break
 return rec_str

# 登录设备
def loginDevice():
 global DEBUG_LOG
 #确认登录失败的条件，或者，不可能失败
 while True:
  print("等待登录... ... ")
  time.sleep(3)
  at_write("\r\n",3,debug_serial,"OK")
  result = at_read(debug_serial)

  with open(DEBUG_LOG, 'a') as file_object:
   file_object.write(result)

  if "login:" in result:
   at_write("root\r\n",3,debug_serial,"OK")
   print("账号输入成功")
   time.sleep(2)
   at_write("oelinux123\r\n",3,debug_serial,"OK")
   print("密码输入成功")
  elif "~ #" in result:
   print("登录成功")
   at_write("echo 2 >/proc/sys/kernel/printk\r\n",3,debug_serial,"OK")
   break
  else:
   continue 

#检查debug口通信状态
def check_port_status():
 global debug_serial
 if debug_serial == None:
  try:
   debug_serial = serial.Serial(DEBUG_PORT,BAUDRATE)
  except:
   print("at口连接失败，请检查端口")
   sys.exit()

# 写入运行次数到日志
def writeRuntimesToLog():
 global runTimes
 with open(DEBUG_LOG, 'a+') as file_object:
  file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 runTimes += 1

# 进入测试接口
def intoTestInterface_testsdk(debug_serial,logFile):
 at_write("cd /data\r\n./test_sdk_api\r\n",3,debug_serial,"OK")
 result = at_read(debug_serial,logFile)

# 退出测试接口
def exit_testsdk(debug_serial,logFile):
 at_write("-1\n-1\n",3,debug_serial,"OK")
 result = at_read(debug_serial,logFile)

# 返回测试接口
def back_testsdk(debug_serial,logFile):
 at_write("-1\n",3,debug_serial,"OK")
 result = at_read(debug_serial,logFile)
 


def get_pid():
    # 获取初始PID
    at_write("pgrep kworker\r\n", 3, debug_serial, "OK")
    all_PID1 = at_read(debug_serial, DEBUG_LOG)
    time.sleep(1)
    return all_PID1

def extract_kworker_pids(output):
    # 使用正则表达式提取包含数字并且后面紧跟着 \r 的内容，同时排除带有时间戳的内容
    pattern = re.compile(r'(?<!\d{10}\.\d{6}:\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\b(\d+)\r')
    kworker_pids = pattern.findall(''.join(output))
    # 去掉第一位
    if kworker_pids:
        kworker_pids = kworker_pids[1:]
    print(kworker_pids)
    return kworker_pids


def check_pid_change():
    # 获取初始PID
    all_PID1 = get_pid()
    kworker_PID1 = extract_kworker_pids(all_PID1)
    # 等待一段时间
    time.sleep(10)  # 例如等待10秒
    # 再次获取PID
    all_PID2 = get_pid()
    kworker_PID2 = extract_kworker_pids(all_PID2)
    
    if kworker_PID1 != kworker_PID2:
        print("kworker PID发生变化，测试通过")
        return "Pass"
    else:
        print("kworker PID没有变化，测试失败")
        return "Fail"

if __name__ == '__main__':
    check_port_status()
    creatLogFile()
    loginDevice()
    time.sleep(5)
    result = check_pid_change()
    print(result)



